import { _decorator, Component, director, EventTouch, Input, instantiate, math, Node, Prefab, Sprite, v3, Vec3 } from 'cc';
import { Virtual } from './Virtual';
import { PlaneTiltBase } from './PlaneTiltBase';
const { ccclass, property } = _decorator;

@ccclass('UIJoyStick')
export class UIJoyStick extends Component {


    @property(Node)
    private pauseBtn:Node;

    @property(Node)
    private pauseGamePageBtn:Node;

    @property(Node)
    private continueGameBtn:Node;
    @property(Node)
    private backHomeBtn:Node;

    private isGamePause:boolean = false;

    @property(Sprite)
    private bg: Sprite;

    @property(Sprite)
    private dot: Sprite;

    @property(Prefab)
    private bullet0:Prefab;

    @property(Prefab)
    private missilePrefab:Prefab;

    private radius:number = 40;

    private initBgPos:Vec3 = new Vec3();

    @property(Node)
    private player_bullet_root:Node;


    @property(Node)
    private buffBtn:Node;


    @property(Node)
    private speedBtn:Node;


    @property(Node)
    private missileBtn:Node;


    @property(Node)
    private radarBtn:Node;

    private moveSpeed:number = 150;

    private bulletMoveSpeed:number = 200;

    private missileSpeed:number = 500;

    public static isPlayerStop:boolean = false;

    public static isTouching:boolean = false;

    private planeTiltBase:PlaneTiltBase;

    private player:Node;

    start() {
        this.node.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);

        this.bg.node.active = false;

        this.initBgPos = this.bg.node.getWorldPosition().clone();

        this.player = this.node.getChildByName("player");

        this.planeTiltBase = this.player.getComponent(PlaneTiltBase);

        this.schedule(() => {

            if (this.isGamePause) {
                return;
            }

            const playerMeta = this.planeTiltBase.getPlayerPosAndAngle();

            const pos = playerMeta.position;
            const angle = playerMeta.angle;

            const node0 = instantiate(this.bullet0);
            node0.angle = angle;
            node0.setPosition(v3(pos.x - 10, pos.y, 0));

            const node1 = instantiate(this.bullet0);
            node1.angle = angle;
            node1.setPosition(v3(pos.x + 10, pos.y, 0));

            this.player_bullet_root.addChild(node0);
            this.player_bullet_root.addChild(node1);

        }, 0.2, 10000000, 0);


        this.schedule(() => {
            if (this.isGamePause) {
                return;
            }

            this.playerBootMissile();

        }, 3, 10000000, 3);
        this.missileBtn.on(Node.EventType.TOUCH_END, () => {
            if (this.isGamePause) {
                return;
            }
            this.playerBootMissile();
        });

        this.pauseBtn.on(Node.EventType.TOUCH_END, () => {
            this.pauseGamePageBtn.active = true;
            this.isGamePause = !this.isGamePause;
        });

        this.radarBtn.on(Node.EventType.TOUCH_END, () => {
            console.log("radarBtn...");
        });
        this.speedBtn.on(Node.EventType.TOUCH_END, () => {
            console.log("radarBtn...");
        });
        this.buffBtn.on(Node.EventType.TOUCH_END, () => {
            console.log("radarBtn...");
        });

        this.continueGameBtn.on(Node.EventType.TOUCH_END, () => {
            this.isGamePause = !this.isGamePause;
            this.pauseGamePageBtn.active = false;
        });

        this.backHomeBtn.on(Node.EventType.TOUCH_END, () => {
            director.loadScene("game");
        });
    }

    private playerBootMissile() {
        const node = instantiate(this.missilePrefab);

        const playerMeta = this.planeTiltBase.getPlayerPosAndAngle();

        const pos = playerMeta.position;
        const angle = playerMeta.angle;

        node.angle = angle;
        node.setPosition(pos);

        this.player_bullet_root.addChild(node);
    }

    update(deltaTime: number) {
        if (!UIJoyStick.isPlayerStop) {
            const playerMeta = this.planeTiltBase.getPlayerPosAndAngle();
            const angle = playerMeta.angle;
            if (angle > 0) {
                const pos = playerMeta.position;
                var newPos = this.movePoint(pos.x, pos.y, angle, this.moveSpeed * deltaTime)

                this.player.setPosition(newPos);
            }
        }

        const playerBullets = this.player_bullet_root.children;
        for (const blt of playerBullets) {

            const pos = blt.position;

            if (pos.x > 500 || pos.x < -500 || pos.y > 800 || pos.y < -800) {
                    //console.log("bullet destory:" + blt.name)
                    blt.destroy();
                    continue;
            }

            if (this.isGamePause) {
                continue;
            }

            const name = blt.name;
            if (name == 'bullet0') {
                var newPos = this.movePoint(pos.x, pos.y, blt.angle, this.bulletMoveSpeed * deltaTime);

                blt.setPosition(newPos);
            } else if (name == 'missile') {
                var newPos = this.movePoint(pos.x, pos.y, blt.angle, this.missileSpeed * deltaTime);

                blt.setPosition(newPos);
            }
        }
    }

    private onTouchStart(eventTouch:EventTouch) {
        
        this.bg.node.active = true;

        eventTouch.currentTarget;
        eventTouch.target;

        UIJoyStick.isPlayerStop = false;

        const x = eventTouch.touch.getUILocationX();
        const y = eventTouch.touch.getUILocationY();

        this.bg.node.setWorldPosition(x, y, 0);
    }

    private onTouchEnd(eventTouch:EventTouch) {
        this.dot.node.setPosition(0, 0, 0);

        Virtual.h = 0;
        Virtual.v = 0;

        this.bg.node.setWorldPosition(this.initBgPos);

        UIJoyStick.isPlayerStop = true;

        UIJoyStick.isTouching = false;
        PlaneTiltBase.lastChangeTime = -1;

        this.planeTiltBase.onPlayerTouchEnd();
    }

    private onTouchMove(eventTouch:EventTouch) {
        UIJoyStick.isTouching = true;

        const x = eventTouch.touch.getUILocationX();
        const y = eventTouch.touch.getUILocationY();

        const worldPos = new Vec3(x, y, 0);
        const localPos = new Vec3();

        this.bg.node.inverseTransformPoint(localPos, worldPos);

        const dotPos = v3();
        const len = localPos.length();

        localPos.normalize();

        Vec3.scaleAndAdd(dotPos, v3(), localPos, math.clamp(len, 0,  this.radius));

        this.dot.node.setPosition(dotPos);
        
        const angle = this.calculateAnglev2(dotPos.x, dotPos.y);

        this.planeTiltBase.setPlayerAngle(angle);

        Virtual.h = this.dot.node.position.x / this.radius;
        Virtual.v = this.dot.node.position.y / this.radius;
    }

    /**
     * 
     *  计算一条经过x,y和0.0的直线和竖直向上方向上的夹角，逆时针方向
     * 
     * @param x 
     * @param y 
     * @returns 
     */
    private calculateAnglev2(x, y):number {
        // 处理原点情况（题目隐含(x,y)非原点，但为健壮性添加）
        if (x === 0 && y === 0) {
            return 0;
        }
        
        // 计算标准极角（从正x轴逆时针，弧度）
        const angleRad = Math.atan2(y, x);
        // 转换为角度
        let angleDeg = angleRad * (180 / Math.PI);
        
        // 转换为从正y轴开始的角度：标准角度 - 90°
        let result = angleDeg - 90;
        
        // 调整到0-360度范围
        result = (result + 360) % 360;
        
        return result;
    }

    /**
    * 计算点在指定方向移动后的坐标
    * 坐标系：竖直向上为0度，水平向左为90度，竖直向下为180度，水平向右为270度（逆时针方向）
    * 
    * @param {number} x - 初始x坐标
    * @param {number} y - 初始y坐标
    * @param {number} n - 倾斜度数（0-360）
    * @param {number} s - 移动距离（正数表示沿方向移动，负数表示反方向移动）
    * @return {Object} 包含新坐标的对象 {x: newX, y: newY}
    */
    private movePoint(x, y, n, s) {
        // 规范化角度到[0, 360)范围
        n = n % 360;
        if (n < 0) {
            n += 360;
        }
        
        // 转换为弧度
        const nRad = n * Math.PI / 180;
        
        // 计算方向向量分量（基于坐标系定义）
        // x方向：-sin(n)，y方向：cos(n)
        const dx = -s * Math.sin(nRad);
        const dy = s * Math.cos(nRad);
        
        // 计算新坐标
        return v3(x + dx, y + dy, 0);
    }
}

